package org.karelun.gef.commands;

import java.util.ArrayList;
import java.util.List;

import org.karelun.gef.helper.ConstantMessages;
import org.karelun.gef.model.AbstractConnectionModel;
import org.karelun.gef.model.AttributeModel;
import org.karelun.gef.model.BaseClassModel;
import org.karelun.gef.model.ClassModel;
import org.karelun.gef.model.DiagramModel;
import org.karelun.gef.model.MethodModel;
import org.karelun.gef.model.Node;

public class DeleteNodeCommand extends AbstractCommand {
	
	private Object parent;

	private Node node;

	public void setParent(Object parent) {
		this.parent = parent;
	}

	public void setNode(Object model) {
		if (model instanceof Node)
			node = (Node) model;
	}

	public void execute() {
		if (parent instanceof DiagramModel) {
			DiagramModel diagram = (DiagramModel) parent;
			diagram.removeNode(node);
		} else if (parent instanceof ClassModel) {
			ClassModel classModel = (ClassModel) parent;
			BaseClassModel model=(BaseClassModel) node;
			removeAttribute(classModel,model);
		}

		List<AbstractConnectionModel> source = node.getModelSourceConnection();
		List<AbstractConnectionModel> sourceConns = new ArrayList<AbstractConnectionModel>();
		
		if (source != null && !source.isEmpty()) {
			sourceConns.addAll(source);
			for (int i = 0; i < sourceConns.size(); i++) {
				AbstractConnectionModel connection = (AbstractConnectionModel) sourceConns
				.get(i);
				connection.detachSource();
				connection.detachTarget();
				
				connection.removeToDiagram();
			}
			sourceConns.clear();
		}

		List<AbstractConnectionModel> target = node.getModelTargetConnection();
		List<AbstractConnectionModel> targetConns = new ArrayList<AbstractConnectionModel>();
		
		if (target != null && !target.isEmpty()) {
			targetConns.addAll(target);
			for (int i = 0; i < targetConns.size(); i++) {
				AbstractConnectionModel connection = (AbstractConnectionModel) targetConns
						.get(i);
				connection.detachSource();
				connection.detachTarget();
				
				connection.removeToDiagram();
			}
			targetConns.clear();
		}
	}

	private void removeAttribute(ClassModel classModel, BaseClassModel model) {
		if(model instanceof AttributeModel)
			classModel.removeAttribute((AttributeModel)model);
		else if(model instanceof MethodModel)
			classModel.removeMethod((MethodModel)model);
	}

	public String getLabel() {
		return ConstantMessages.DeleteNodeCommand_Label_Text;
	}

	public void redo() {
		execute();
	}

	public void undo() {
		if (parent instanceof DiagramModel) {
			DiagramModel diagram = (DiagramModel) parent;
			diagram.addNode(node);
		} else if (parent instanceof ClassModel) {
			ClassModel classModel = (ClassModel) parent;
			addAttribute(classModel,(BaseClassModel) node);
		}
	}

	private void addAttribute(ClassModel classModel, BaseClassModel model) {
		if(model instanceof AttributeModel)
			classModel.addAttribute((AttributeModel)model);
		else if(model instanceof MethodModel)
			classModel.addMethod((MethodModel)model);
	}
}